﻿using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;

namespace Portal
{
    public class XImage
    {

        public Color tBackground;

        public Color tBorder;

        public Color tShadow;

        public int tQuality;

        public string markPosition;

        /// <summary>  

        /// 图片参数预定义  

        /// </summary>  

        static Hashtable htmimes = new Hashtable();

        internal readonly string AllowExt = ".jpe|.jpeg|.jpg|.png|.tif|.tiff|.bmp|.gif";

        public XImage()
        {

            tBackground = Color.Transparent;

            tBorder = Color.Transparent;

            tShadow = Color.Transparent;

            tQuality = 100;

            markPosition = "左下角";

            #region 图片类型预定义

            htmimes[".jpe"] = "image/jpeg";

            htmimes[".jpeg"] = "image/jpeg";

            htmimes[".jpg"] = "image/jpeg";

            htmimes[".png"] = "image/png";

            htmimes[".tif"] = "image/tiff";

            htmimes[".tiff"] = "image/tiff";

            htmimes[".bmp"] = "image/bmp";

            htmimes[".gif"] = "image/gif";

            #endregion

        }

        #region 下载指定URL图片并保存

        /// <summary>  
        /// 下载指定URL的文件并保存到指定目录  
        /// </summary>  
        /// <param name="strUrl"></param>
        /// <param name="file"></param>  
        public void DownloadImage(string strUrl, string file)
        {

            var wc = new System.Net.WebClient();

            wc.DownloadFile(strUrl, file);

        }

        #endregion

        #region C#自动生成缩略图

        /// <summary>  

        /// 按给定名字确定颜色  

        /// </summary>  

        /// <param name="name"></param>  

        /// <returns></returns>  

        public Color ToColor(string name)
        {

            if (name == "白色") return Color.White;

            if (name == "红色") return Color.Red;

            if (name == "蓝色") return Color.Blue;

            if (name == "绿色") return Color.Green;

            if (name == "黑色") return Color.Black;

            if (name == "灰色") return Color.DarkGray;

            if (name == "黄色") return Color.Yellow;

            if (name == "紫色") return Color.Cyan;

            if (name == "无色") return Color.Transparent;

            return Color.Transparent;

        }

        /// <summary>  

        /// 按名字设置各种颜色，可以自行扩充:)  

        /// </summary>  

        /// <param name="name"></param>  

        /// <returns></returns>  

        public int ToQuality(string name)
        {

            return int.Parse(name.Replace("%", ""));

        }

        /// <summary>   

        /// 获取图像编码解码器的所有相关信息   

        /// </summary>   

        /// <param name="mimeType">包含编码解码器的多用途网际邮件扩充协议 (MIME) 类型的字符串</param>   

        /// <returns>返回图像编码解码器的所有相关信息</returns>   

        private static ImageCodecInfo GetCodecInfo(string mimeType)
        {

            var codecInfo = ImageCodecInfo.GetImageEncoders();

            return codecInfo.FirstOrDefault(ici => ici.MimeType == mimeType);
        }

        /// <summary>   

        /// 检测扩展名的有效性   

        /// </summary>   

        /// <param name="sExt">文件名扩展名</param>   

        /// <returns>如果扩展名有效,返回true,否则返回false.</returns>   

        private bool CheckValidExt(string sExt)
        {
            var aExt = AllowExt.Split(Convert.ToChar("|"));

            return aExt.Any(filetype => filetype.ToLower() == sExt);

        }

        /// <summary>   

        /// 保存图片   

        /// </summary>   

        /// <param name="image">Image 对象</param>   

        /// <param name="savePath">保存路径</param>   

        /// <param name="ici">指定格式的编解码参数</param>   

        private void SaveImage(System.Drawing.Image image, string savePath, ImageCodecInfo ici)
        {

            //设置 原图片 对象的 EncoderParameters 对象   

            var parameters = new EncoderParameters(1);

            parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, ((long)tQuality));

            image.Save(savePath, ici, parameters);

            parameters.Dispose();

        }
        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="sourceImagePath">原图片路径(相对路径)</param>   
        /// <param name="thumbnailImagePath">生成的缩略图路径,如果为空则保存为原图片路径(相对路径)</param>   
        /// <param name="proportion">缩放比列</param>
        public void ToThumbnail(string sourceImagePath, string thumbnailImagePath, uint maxThumbnailImageHeight, uint maxThumbnailImageWidth)
        {     // .先检查图片格式等信息  

            var model = 2;
            int thumbnailImageHeight;
            int thumbnailImageWidth;
            var ThumbnailImagePath = thumbnailImagePath;


            var SourceImagePath = sourceImagePath;

            var sExt = SourceImagePath.Substring(SourceImagePath.LastIndexOf(".")).ToLower();

            if (SourceImagePath == String.Empty)
            {

                throw new NullReferenceException("SourceImagePath is null!");

            }

            if (!CheckValidExt(sExt))
            {

                throw new ArgumentException("原图片文件格式不正确,支持的格式有[ " + AllowExt + " ]", "SourceImagePath");

            }

            // 从原图片创建 Image 对象   

            if (!File.Exists(HttpContext.Current.Server.MapPath(SourceImagePath)))
            {
                return;
            }
            var image = Image.FromFile(HttpContext.Current.Server.MapPath(SourceImagePath));

            double fs = (image.Height * 1.0 / maxThumbnailImageHeight) > (image.Width * 1.0 / maxThumbnailImageWidth) ? (double)(image.Height * 1.0 / maxThumbnailImageHeight) : (double)(image.Width * 1.0 / maxThumbnailImageWidth);

            thumbnailImageHeight = (int)(image.Height / fs);
            thumbnailImageWidth = (int)(image.Width / fs);
            // .计算图片的位置、尺寸等信息  

            int tWidth, tHeight, tLeft, tTop;
            if (model == 1)
            {
                var fScale = (double)thumbnailImageHeight / (double)thumbnailImageWidth; // 高度宽度比  

                if (((double)image.Width * fScale) > (double)image.Height) // 如果原图比较宽  
                {

                    tWidth = thumbnailImageWidth;

                    tHeight = (int)((double)image.Height * (double)tWidth / (double)image.Width);

                    tLeft = 0;

                    tTop = (thumbnailImageHeight - tHeight) / 2;

                }

                else
                {

                    tHeight = thumbnailImageHeight;

                    tWidth = (int)((double)image.Width * (double)tHeight / (double)image.Height);

                    tLeft = (thumbnailImageWidth - tWidth) / 2;

                    tTop = 0;

                }

                if (tLeft < 0) tLeft = 0;

                if (tTop < 0) tTop = 0;

                if (tBorder != Color.Transparent)
                {

                    tWidth -= 2;

                    tHeight -= 2;

                    tLeft++;

                    tTop++;

                }

                if (tShadow != Color.Transparent)
                {

                    tWidth -= 1;

                    tHeight -= 1;

                }
            }
            else if (model == 2)
            {
                tWidth = thumbnailImageWidth;

                tHeight = thumbnailImageHeight;

                tLeft = 0;

                tTop = 0;

            }
            else
            {
                tWidth = thumbnailImageWidth;

                tHeight = thumbnailImageHeight;

                tLeft = 0;

                tTop = 0;

            }

            //用指定的大小和格式初始化 Bitmap 类的新实例   

            //Bitmap bitmap = new Bitmap(ThumbnailImageWidth, num, PixelFormat.FormatbppArgb);  

            var bitmap = new Bitmap(thumbnailImageWidth, thumbnailImageHeight, PixelFormat.Format32bppArgb);

            //从指定的 Image 对象创建新 Graphics 对象   

            Graphics graphics = Graphics.FromImage(bitmap);

            //清除整个绘图面并以透明背景色填充  

            graphics.Clear(tBackground != Color.Transparent ? tBackground : Color.Transparent);

            // 添加阴影  

            if (tShadow != Color.Transparent)
            {

                var shPen = new Pen(tShadow);

                graphics.DrawLine(shPen, new Point(1, thumbnailImageHeight - 1), new Point(thumbnailImageWidth - 1, thumbnailImageHeight - 1));

                graphics.DrawLine(shPen, new Point(thumbnailImageWidth - 1, 1), new Point(thumbnailImageWidth - 1, thumbnailImageHeight - 1));

            }

            // 添加边框  

            if (tBorder != Color.Transparent)
            {
                var bdPen = new Pen(tBorder);

                graphics.DrawRectangle(bdPen,
                                       tShadow != Color.Transparent
                                           ? new Rectangle(0, 0, thumbnailImageWidth - 2, thumbnailImageHeight - 2)
                                           : new Rectangle(0, 0, thumbnailImageWidth - 1, thumbnailImageHeight - 1));
            }

            //在指定位置并且按指定大小绘制 原图片 对象   

            graphics.DrawImage(image, new Rectangle(tLeft, tTop, tWidth, tHeight));

            image.Dispose();

            try
            {

                //将此 原图片 以指定格式并用指定的编解码参数保存到指定文件   

                var savepath = (string.IsNullOrEmpty(ThumbnailImagePath) ? SourceImagePath : ThumbnailImagePath);

                SaveImage(bitmap, HttpContext.Current.Server.MapPath(savepath), GetCodecInfo((string)htmimes[sExt]));

            }

            finally
            {

                bitmap.Dispose();

                graphics.Dispose();

            }

        }
        /// <summary>   
        /// 生成缩略图   
        /// </summary>   
        /// <param name="sourceImagePath">原图片路径(相对路径)</param>   
        /// <param name="thumbnailImagePath">生成的缩略图路径,如果为空则保存为原图片路径(相对路径)</param>   
        /// <param name="thumbnailImageWidth">缩略图的宽度（高度与按源图片比例自动生成）</param>
        /// <param name="thumbnailImageHeight"></param>
        /// <param name="model">图片缩放模式(model=1 自适应 model=2 拉伸 model=3 裁剪)</param>   
        public void ToThumbnail(string sourceImagePath, string thumbnailImagePath, int thumbnailImageWidth, int thumbnailImageHeight, int model)
        {

            // .先检查图片格式等信息  



            var ThumbnailImagePath = thumbnailImagePath;

            var SourceImagePath = sourceImagePath;

            var sExt = SourceImagePath.Substring(SourceImagePath.LastIndexOf(".")).ToLower();

            if (SourceImagePath == String.Empty)
            {

                throw new NullReferenceException("SourceImagePath is null!");

            }

            if (!CheckValidExt(sExt))
            {

                throw new ArgumentException("原图片文件格式不正确,支持的格式有[ " + AllowExt + " ]", "SourceImagePath");

            }

            // 从原图片创建 Image 对象   

            var image = Image.FromFile(HttpContext.Current.Server.MapPath(SourceImagePath));

            // .计算图片的位置、尺寸等信息  

            int tWidth, tHeight, tLeft, tTop;
            if (model == 1)
            {
                var fScale = (double)thumbnailImageHeight / (double)thumbnailImageWidth; // 高度宽度比  

                if (((double)image.Width * fScale) > (double)image.Height) // 如果原图比较宽  
                {

                    tWidth = thumbnailImageWidth;

                    tHeight = (int)((double)image.Height * (double)tWidth / (double)image.Width);

                    tLeft = 0;

                    tTop = (thumbnailImageHeight - tHeight) / 2;

                }

                else
                {

                    tHeight = thumbnailImageHeight;

                    tWidth = (int)((double)image.Width * (double)tHeight / (double)image.Height);

                    tLeft = (thumbnailImageWidth - tWidth) / 2;

                    tTop = 0;

                }

                if (tLeft < 0) tLeft = 0;

                if (tTop < 0) tTop = 0;

                if (tBorder != Color.Transparent)
                {

                    tWidth -= 2;

                    tHeight -= 2;

                    tLeft++;

                    tTop++;

                }

                if (tShadow != Color.Transparent)
                {

                    tWidth -= 1;

                    tHeight -= 1;

                }
            }
            else if (model == 2)
            {
                tWidth = thumbnailImageWidth;

                tHeight = thumbnailImageHeight;

                tLeft = 0;

                tTop = 0;

            }
            else
            {
                tWidth = thumbnailImageWidth;

                tHeight = thumbnailImageHeight;

                tLeft = 0;

                tTop = 0;

            }

            //用指定的大小和格式初始化 Bitmap 类的新实例   

            //Bitmap bitmap = new Bitmap(ThumbnailImageWidth, num, PixelFormat.FormatbppArgb);  

            var bitmap = new Bitmap(thumbnailImageWidth, thumbnailImageHeight, PixelFormat.Format32bppArgb);

            //从指定的 Image 对象创建新 Graphics 对象   

            Graphics graphics = Graphics.FromImage(bitmap);

            //清除整个绘图面并以透明背景色填充  

            graphics.Clear(tBackground != Color.Transparent ? tBackground : Color.Transparent);

            // 添加阴影  

            if (tShadow != Color.Transparent)
            {

                var shPen = new Pen(tShadow);

                graphics.DrawLine(shPen, new Point(1, thumbnailImageHeight - 1), new Point(thumbnailImageWidth - 1, thumbnailImageHeight - 1));

                graphics.DrawLine(shPen, new Point(thumbnailImageWidth - 1, 1), new Point(thumbnailImageWidth - 1, thumbnailImageHeight - 1));

            }

            // 添加边框  

            if (tBorder != Color.Transparent)
            {
                var bdPen = new Pen(tBorder);

                graphics.DrawRectangle(bdPen,
                                       tShadow != Color.Transparent
                                           ? new Rectangle(0, 0, thumbnailImageWidth - 2, thumbnailImageHeight - 2)
                                           : new Rectangle(0, 0, thumbnailImageWidth - 1, thumbnailImageHeight - 1));
            }

            //在指定位置并且按指定大小绘制 原图片 对象   

            graphics.DrawImage(image, new Rectangle(tLeft, tTop, tWidth, tHeight));

            image.Dispose();

            try
            {

                //将此 原图片 以指定格式并用指定的编解码参数保存到指定文件   

                var savepath = (string.IsNullOrEmpty(ThumbnailImagePath) ? SourceImagePath : ThumbnailImagePath);

                SaveImage(bitmap, HttpContext.Current.Server.MapPath(savepath), GetCodecInfo((string)htmimes[sExt]));

            }

            finally
            {

                bitmap.Dispose();

                graphics.Dispose();

            }

        }

        #endregion

        #region C#给图片添加水印

        public void Mark(string sourceImagePath, string markString)
        {

            // .先检查图片格式等信息  

            string markImagePath = sourceImagePath;

            var SourceImagePath = sourceImagePath;
            if (SourceImagePath == null) throw new ArgumentNullException("SourceImagePath");

            var sExt = SourceImagePath.Substring(SourceImagePath.LastIndexOf(".")).ToLower();

            if (SourceImagePath.ToString() == System.String.Empty)
            {

                throw new NullReferenceException("SourceImagePath is null!");

            }

            if (!CheckValidExt(sExt))
            {

                throw new ArgumentException("原图片文件格式不正确,支持的格式有[ " + AllowExt + " ]", "SourceImagePath");

            }

            // 从原图片创建 Image 对象   

            System.Drawing.Image image = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(SourceImagePath));

            //用指定的大小和格式初始化 Bitmap 类的新实例   

            var bitmap = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb);

            //从指定的 Image 对象创建新 Graphics 对象   

            var graphics = Graphics.FromImage(bitmap);

            //在指定位置并且按指定大小绘制 原图片 对象   

            graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));

            #region 绘制水印

            // 设置水印字体  

            var fHeight = image.Height / 5;

            if (fHeight > 16) fHeight = 16;

            var drawFont = new Font("Arial", fHeight);

            // 设置水印文字位置，默认为左下角  

            float x = 4;

            float y = image.Height - drawFont.Height - 4;

            if (markPosition == "左上角")
            {

                y = 4;

            }

            if (markPosition == "右上角")
            {

                x = image.Width - markString.Length * fHeight / 2 - fHeight;

                y = 4;

            }

            if (markPosition == "右下角")
            {

                x = image.Width - markString.Length * fHeight / 2 - fHeight;

            }

            if (markPosition == "图片中间")
            {

                x = image.Width / 2 - markString.Length * fHeight / 2;

                y = image.Height / 2 - fHeight / 2;

            }

            var drawFormat = new StringFormat { FormatFlags = StringFormatFlags.NoWrap };



            // 设置水印文字颜色，先绘制一个黑色字作为阴影，再绘制白色字，这样比较显眼；  

            var drawBrush = new SolidBrush(Color.Black);

            graphics.DrawString(markString, drawFont, drawBrush, x, y, drawFormat);

            drawBrush.Color = Color.White;

            graphics.DrawString(markString, drawFont, drawBrush, x - 1, y - 1, drawFormat);

            #endregion

            image.Dispose();

            try
            {

                //将此 原图片 以指定格式并用指定的编解码参数保存到指定文件   

                string savepath = SourceImagePath;

                SaveImage(bitmap, HttpContext.Current.Server.MapPath(savepath), GetCodecInfo((string)htmimes[sExt]));

            }

            finally
            {

                bitmap.Dispose();

                graphics.Dispose();

            }

        }

        #endregion

        /// <summary>
        /// 从文章内容中获取第一张图片，用作文章缩略图
        /// </summary>
        /// <param name="articleContent"></param>
        /// <returns></returns>
        public static string GetImageUrlFromArticle(string articleContent)
        {
            var r = new Regex(@"<IMG[^>]+src=\s*(?:'(?<src>[^']+)'|""(?<src>[^""]+)""|(?<src>[^>\s]+))\s*[^>]*>", RegexOptions.IgnoreCase);
            MatchCollection mc = r.Matches(articleContent);
            if (mc.Count != 0)
            {
                return mc[0].Groups["src"].Value.ToLower();
            }
            return null;
        }

    }
}
